package org.dromara.system.service.impl.permission;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.converter.MachineConverters;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.common.BasePageReqDTO;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.enums.MachineConstant;
import org.dromara.system.enums.QueryTypeEnum;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.util.TreeUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 王星
 * @date 2024/8/2 下午4:57
 */
@Service
@RequiredArgsConstructor
public class PermissionBaseService {

    @Resource
    private SysUserMapper sysUserMapper;

    private static void addNextUser(ArrayList<SysUserVo> addSysUsers, List<SysUserVo> sysUsers) {
        if (CollUtil.isNotEmpty(sysUsers)) {
            sysUsers.forEach(t1 -> {
                addSysUsers.add(t1);
                addNextUser(addSysUsers, t1.getChildren());
            });
        }
    }


    //一级全部 下级个人
    public SysUser assignPermission(BasePageReqDTO reqQueryDTO) {
        Long userId = reqQueryDTO.getUserId();
        if (ObjectUtil.isNull(userId)) {
            userId = LoginHelper.getUserId();
        }
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (ObjectUtil.notEqual(userId, MachineConstant.ADMIN)) {
            if (ObjectUtil.equal(sysUser.getPId(), MachineConstant.ADMIN)) {
                reqQueryDTO.setUserIds(findUser(sysUser));
            } else {
                reqQueryDTO.setUserIds(Collections.singletonList(userId));
            }
        }
        reqQueryDTO.setUserId(null);
        return sysUser;
    }

    //admin全部 各级自己
    public void aloneAssignPermission(BasePageReqDTO reqQueryDTO) {
        Long userId = reqQueryDTO.getUserId();
        if (ObjectUtil.isNull(userId)) {
            userId = LoginHelper.getUserId();
        }
        if (ObjectUtil.notEqual(userId, MachineConstant.ADMIN)) {
            reqQueryDTO.setUserIds(Collections.singletonList(userId));
        }
        reqQueryDTO.setUserId(null);
    }



    public List<Long> findUser(SysUser sysUser) {
        //缓存
        List<SysUser> sysUsers = sysUserMapper.selectList(Wrappers.<SysUser>lambdaQuery()
            .select(SysUser::getPId, SysUser::getUserId)
            .eq(SysUser::getOneId, sysUser.getOneId()));
        List<SysUserVo> SysUserVoList=  MachineConverters.INSTANCE.toSysUserVoList(sysUsers);
        //下级直属
        List<SysUserVo> sysUsersTree = TreeUtil.newListToTree(SysUserVoList, SysUserVo::setChildren, SysUserVo::getUserId,
            SysUserVo::getPId, (node) -> ObjectUtil.equal(sysUser.getPId(), node.getPId()));
        SysUserVo headed = sysUsersTree.stream().filter(t1 -> ObjectUtil.equal(t1.getUserId(), sysUser.getUserId())).findFirst().orElse(null);
        return nextUser(headed, QueryTypeEnum.ALL.getCode()).stream()
            .map(SysUserVo::getUserId)
            .collect(Collectors.toList());
    }

    public List<SysUserVo> nextUser(SysUserVo sysUser, Integer type) {
        ArrayList<SysUserVo> addSysUsers = Lists.newArrayList();
        if (ObjectUtil.equal(type, QueryTypeEnum.TEAM.getCode())) {
            addNextUser(addSysUsers, sysUser.getChildren());
            if (CollUtil.isEmpty(addSysUsers)) {
                SysUserVo sysUserNew = new SysUserVo();
                sysUserNew.setUserId(-1L);
                addSysUsers.add(sysUserNew);
            }
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.ALL.getCode())) {
            addSysUsers.add(sysUser);
            addNextUser(addSysUsers, sysUser.getChildren());
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.DIRECT.getCode())) {
            addSysUsers.add(sysUser);
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.JUNIOR.getCode())) {
            addSysUsers.addAll(sysUser.getChildren());
            if (CollUtil.isEmpty(addSysUsers)) {
                SysUserVo sysUserNew = new SysUserVo();
                sysUserNew.setUserId(-1L);
                addSysUsers.add(sysUserNew);
            }
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.DIRECT_AND_DIRECT.getCode())) {
            addSysUsers.add(sysUser);
            addSysUsers.addAll(sysUser.getChildren());
        }
        if (ObjectUtil.equal(type, QueryTypeEnum.AGENT.getCode())) {
            if (CollUtil.isNotEmpty(sysUser.getChildren())) {
                sysUser.getChildren().forEach(t1 -> {
                    addNextUser(addSysUsers, t1.getChildren());
                });
            }
            if (CollUtil.isEmpty(addSysUsers)) {
                SysUserVo sysUserNew = new SysUserVo();
                sysUserNew.setUserId(-1L);
                addSysUsers.add(sysUserNew);
            }
        }
        return addSysUsers;
    }


}
